package com.mazaiting.instructions.comparisons;

import com.mazaiting.instructions.base.BranchInstruction;
import com.mazaiting.rtda.MtFrame;
import com.mazaiting.rtda.MtOperandStack;

/**
 * if_icmp<cond>指令把栈顶的两个int变量弹出，然后进行比较，满足条件则跳转
 *
 * @author mazaiting
 * @since 2021/8/15
 */
public class IfIcmpInstruction {
    /**
     * 条件判断相等
     */
    public static class IfIcmpEq extends BranchInstruction {
        @Override
        public void execute(MtFrame frame) {
            MtOperandStack stack = frame.getOperandStack();
            int v1 = stack.popInt();
            int v2 = stack.popInt();
            if (v2 == v1) {
                branch(frame, offset);
            }
        }

        @Override
        public String toString() {
            return "if_icmpeq " + offset;
        }
    }

    /**
     * 条件判断不等于
     */
    public static class IfIcmpNe extends BranchInstruction {
        @Override
        public void execute(MtFrame frame) {
            MtOperandStack stack = frame.getOperandStack();
            int v1 = stack.popInt();
            int v2 = stack.popInt();
            if (v2 != v1) {
                branch(frame, offset);
            }
        }

        @Override
        public String toString() {
            return "if_icmpne " + offset;
        }
    }

    /**
     * 条件判断小于
     */
    public static class IfIcmpLt extends BranchInstruction {
        @Override
        public void execute(MtFrame frame) {
            MtOperandStack stack = frame.getOperandStack();
            int v1 = stack.popInt();
            int v2 = stack.popInt();
            if (v2 < v1) {
                branch(frame, offset);
            }
        }

        @Override
        public String toString() {
            return "if_icmplt " + offset;
        }
    }

    /**
     * 条件判断小于等于
     */
    public static class IfIcmpLe extends BranchInstruction {
        @Override
        public void execute(MtFrame frame) {
            MtOperandStack stack = frame.getOperandStack();
            int v1 = stack.popInt();
            int v2 = stack.popInt();
            if (v2 <= v1) {
                branch(frame, offset);
            }
        }

        @Override
        public String toString() {
            return "if_icmple " + offset;
        }
    }

    /**
     * 条件判断大于
     */
    public static class IfIcmpGt extends BranchInstruction {
        @Override
        public void execute(MtFrame frame) {
            MtOperandStack stack = frame.getOperandStack();
            int v1 = stack.popInt();
            int v2 = stack.popInt();
            if (v2 > v1) {
                branch(frame, offset);
            }
        }

        @Override
        public String toString() {
            return "if_icmpgt " + offset;
        }
    }

    /**
     * 条件判断大于等于
     */
    public static class IfIcmpGe extends BranchInstruction {
        @Override
        public void execute(MtFrame frame) {
            MtOperandStack stack = frame.getOperandStack();
            int v1 = stack.popInt();
            int v2 = stack.popInt();
            if (v2 >= v1) {
                branch(frame, offset);
            }
        }

        @Override
        public String toString() {
            return "if_icmpge " + offset;
        }
    }
}
